/**
 * GeoSOA/olap4js/OlapAjax.js
 *
 * OlapAjax object
 *
 * Copyright (C) 2009 GeoSOA Research Group, Universite Laval
 * See LICENSE file under this distribution for licensing information
 * 
 * Copyright (C) 2010 AtolCD
 * @author Etienne Dube
 * @since 20090327
 * @author Vincent Plantegenet
 * @since 20100325
  **/

dojo.provide("GeoSOA.olap4js.OlapAjax");

dojo.require("GeoSOA.olap4js.CellSet");
dojo.require("GeoSOA.util.Observable");

/**
 * OlapAjax is an object used to query the olapJSON server, retrieve the
 * result set, parse it to olap4js objects ({@link CellSet}) and notify any
 * observers (e.g. widgets displaying the results) of the new result
 * 
 * @param {Object} options The options
 * @constructor
 */
GeoSOA.olap4js.OlapAjax = function (options) {
	
	var options = options || {};
	
	/**
	 * {String} options.mdxQuery (optional) Initial MDX query to submit
	 * to the server.
	 */
	this._mdxQuery = options.mdxQuery || null;
	this._mdxQueryObj = options.mdxQueryObject || null;
	 
	/**
	 * {String} options.olapJSONServiceURL (optional) Absolute or relative
	 * URL of the web service used to query and retrieve olapJSON data. Due
	 * to the security model of XMLHttpRequest, this must be located on the
	 * same host as the client page (same origin policy). Defaults to a
	 * "SpatialyticsServlet" relative URL (which is the default name of the
	 * reference Java servlet implementation).
	 */
	this._olapJSONServiceURL = options.olapJSONServiceURL || "SpatialyticsServlet";

	/**
	 * {Number} options.olapJSONServiceTimeout (optional) Timeout in
	 * milliseconds for requests to the web service. Defaults to 0 (wait
	 * forever) to help debugging the servlet.
	 */
	this._olapJSONServiceTimeout = options.olapJSONServiceTimeout || 0;

	
	this._cellSet = null;
	this._olapJSON = null;
	
	/**
	 * Observable object for handling the "after response" event
	 */
	this.newRequest = new GeoSOA.util.Observable(this);
	this.afterResponseObservable = new GeoSOA.util.Observable(this);
};


/**
 * Sets the current MDX query
 * 
 * @param {String} mdx The MDX query
 */
GeoSOA.olap4js.OlapAjax.prototype.setMdxQuery = function (mdx) {
	this._mdxQuery = mdx;
};


/**
 * Sets the current MDX query object
 * 
 * @param {AtolCD.olap4js.MDXQuery} mdx The MDX query object
 */
GeoSOA.olap4js.OlapAjax.prototype.setMdxQueryObj = function (mdx_o) {
	this._mdxQueryObj = mdx_o;
};

//Sets both mdx
GeoSOA.olap4js.OlapAjax.prototype.setMdxQueries = function (mdx,mdx_o) {
	this._mdxQuery = mdx;
	this._mdxQueryObj = mdx_o;
};
/**
 * Gets the current MDX query
 * 
 * @return The MDX query
 * @type String
 */
GeoSOA.olap4js.OlapAjax.prototype.getMdxQuery = function () {
	return this._mdxQuery;
};

/**
 * Gets the current MDX query Object
 * 
 * @return The MDX query Object
 * @type AtolCD.olap4js.MDXQuery
 */
GeoSOA.olap4js.OlapAjax.prototype.getMdxQueryObj = function () {
	return this._mdxQueryObj;
};


/**
 * Returns the {@link CellSet} object
 * 
 * @return CellSet object
 * @type Object
 */
GeoSOA.olap4js.OlapAjax.prototype.getCellSet = function () {
	return this._cellSet;
};

/**
 * Response handler function for xhrPost
 * 
 * @param {String} resp Response from the web service
 * @private
 */
GeoSOA.olap4js.OlapAjax.prototype._handleResponse = function (resp) {

	// resp is supposed to be an olapJSON string
	
	// parse it
	var olapJSON = dojo.fromJson(resp);
	
	// construct the olap4js CellSet object
	this._cellSet = new GeoSOA.olap4js.CellSet(olapJSON.cellSet);
	
	// update the current MDX query with the new executed query
	//this._mdxQuery = this._cellSet.metadata.executedQuery;
	
	// update the observers
	this.afterResponseObservable.update();
};

/**
 * Submits the current MDX query to the web service, optionally with an OLAP
 * navop to apply to the query (e.g. "DrillReplace").
 * See {@link GeoSOA.Spatialytics.SOLAPContext.SOLAPToolbar} for a list of supported
 * OLAP navops  
 * 
 * @param {String} OLAPNavOp (optional) The OLAP navop to apply
 * @param {Number} axisOrd (optional) Axis ordinal identifying the clicked
 * member (OLAPNavOP must be specified)
 * @param {Number} positionOrd (optional) Position ordinal (in axis)
 * identifying the clicked member (OLAPNavOP must be specified)
 * @param {Number} memberOrd (optional) Member ordinal (in position)
 * identifying the clicked member (OLAPNavOP must be specified)
 * @public
 */
GeoSOA.olap4js.OlapAjax.prototype.submitQuery = function (OLAPNavOp, axisOrd,
		positionOrd, memberOrd) {

	var that = this; 
	
	that.newRequest.update();

	mdxQ = that._mdxQuery;

	var postContent = {
			"mdxQuery" : mdxQ,
			"outputFormat" : "olapJSON"
	};

	postContent["OLAPNavOp"] = OLAPNavOp;
	postContent["axisOrd"] = axisOrd;
	postContent["positionOrd"] = positionOrd;
	postContent["memberOrd"] = memberOrd;
	
	// do the POST request to the web service
	dojo.xhrPost(
			{
				url: that._olapJSONServiceURL,
				content: postContent,
				contentType: "application/x-www-form-urlencoded; charset=UTF-8",
				handleAs: "text",
				timeout: that._olapJSONServiceTimeout,
				// callback closure function for handling response:
				load: function (response, ioArgs) {
					that._handleResponse(response);
					return response;
				},
				error: function (response, ioArgs) {
					// note: console is a firebug object
					if (console != null) {
						console.error("HTTP status code: ", ioArgs.xhr.status);
					}
					return response;
				}
			}
	);
};


/**
 * Returns a closure that calls the submitQuery function with the current
 * OlapAjax object, to be used as a callback, e.g. in functions such as
 * dojo.addOnLoad()
 * 
 * @return Closure function
 * @type Function
 */
GeoSOA.olap4js.OlapAjax.prototype.getSubmitQueryClosure = function () {
	var that = this;
	return function () {
		that.submitQuery();
	};
};
